package com.wei.czz.framework.common.controller;

import com.wei.czz.common.annotation.Resubmit;
import com.wei.czz.common.dto.common.fileImport.FileImportDto;
import com.wei.czz.common.property.BatchProperty;
import com.wei.czz.common.tool.Result;
import com.wei.czz.common.utils.MD5Utils;
import com.wei.czz.common.vo.common.fileImport.FileImportCreateVo;
import com.wei.czz.common.vo.common.fileImport.FileImportVo;
import com.wei.czz.common.vo.common.fileImport.MergeFileVo;
import com.wei.czz.framework.common.entity.FileImportEntity;
import com.wei.czz.framework.common.manager.FileImportManager;
import lombok.AllArgsConstructor;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import java.io.IOException;
import java.util.List;
import java.util.Objects;

/**
 * Created by IntelliJ IDEA.
 *
 * @author wei
 * date: 2024-05-05 10:47:15
 * className: FileImportController
 * version: 1.0
 * description:
 */
@RestController
@RequestMapping("common/file-import")
@AllArgsConstructor
public class FileImportController {

    private static final Logger log = LoggerFactory.getLogger(FileImportController.class);

    private final BatchProperty batchProperty;

    private final FileImportManager fileImportManager;

    /**
     * 创建文件上传任务接口
     * @param fileImportCreateVo 参数对象
     * @return 结果
     */
    @Resubmit(message = "创建文件上传任务")
    @PutMapping("/create")
    public Result<FileImportDto> createFileImport(@Validated @RequestBody FileImportCreateVo fileImportCreateVo) {
        log.info("开始创建文件上传任务。{}", fileImportCreateVo);

        FileImportDto fileImportDto = fileImportManager.createFileImport(fileImportCreateVo);

        log.info("创建文件上传任务结束");
        return Result.success(fileImportDto);
    }

    /**
     * 切片文件上传接口
     * @param fileImportVo 参数对象
     * @return 结果
     */
    @PostMapping("/upload")
    public Result<FileImportDto> uploadFile(@Validated @ModelAttribute FileImportVo fileImportVo) {
        log.info("开始切片文件上传业务。{}", fileImportVo);

        MultipartFile sliceFile = fileImportVo.getSliceFile();

        try {
            // 计算切片文件md5
            String md5 = MD5Utils.encodeMD5(sliceFile.getBytes());
            if (!StringUtils.equals(md5, fileImportVo.getSliceMd5())) {
                log.info("切片文件md5对比失败。md5={} sliceMd5={}", md5, fileImportVo.getSliceMd5());
                return Result.clientFail("切片文件md5对比失败");
            }
        } catch (IOException e) {
            log.error("切片文件md5值计算异常。message={}", e.getMessage(), e);
            return Result.clientFail("参数校验失败");
        }

        FileImportDto fileImportDto = fileImportManager.uploadFile(fileImportVo);

        log.info("切片文件上传业务结束");
        return Result.success(fileImportDto);
    }

    /**
     * 获取下一个需要上传的切片序号接口
     * @param id 主键
     * @return 结果
     */
    @GetMapping("/next/sliceSequence")
    public Result<Integer> getNextSliceSequence(@RequestParam("id") Long id) {
        log.info("开始获取下一个需要上传的切片序号业务。id={}", id);

        Integer nextSliceSequence = fileImportManager.getNextSliceSequence(id);

        log.info("获取下一个需要上传的切片序号业务结束");
        return Result.success(nextSliceSequence);
    }

    /**
     * 合并切片文件接口
     * @param mergeFileVo 参数对象
     * @return 结果
     */
    @PostMapping("/merge")
    public Result<Object> mergeSliceFile(@Validated @RequestBody MergeFileVo mergeFileVo) {
        log.info("开始合并切片文件业务。{}", mergeFileVo);

        fileImportManager.mergeSliceFile(mergeFileVo);

        log.info("合并切片文件业务结束");
        return Result.success();
    }

    /**
     * 暂停文件上传接口
     * @param fileImport 参数对象
     * @return 结果
     */
    @PostMapping("/pause")
    public Result<Object> pauseUpload(@RequestBody FileImportEntity fileImport) {
        log.info("开始暂停文件上传业务。id={}", fileImport.getId());
        if (Objects.isNull(fileImport.getId())) {
            return Result.clientFail("文件上传记录主键不能为空");
        }

        fileImportManager.pauseUpload(fileImport.getId());

        return Result.success();
    }

    /**
     * 开启文件上传接口
     * @param fileImport 参数对象
     * @return 结果
     */
    @PostMapping("/start")
    public Result<Object> startUpload(@RequestBody FileImportEntity fileImport) {
        log.info("开始开启文件上传业务。id={}", fileImport.getId());
        if (Objects.isNull(fileImport.getId())) {
            return Result.clientFail("文件上传记录主键不能为空");
        }

        fileImportManager.startUpload(fileImport.getId());

        log.info("开启文件上传业务结束");
        return Result.success();
    }

    /**
     * 删除文件上传接口
     * @param idList 主键列表
     * @return 结果
     */
    @DeleteMapping("/delete")
    public Result<Object> deleteFileImport(@RequestBody List<Long> idList) {
        log.info("开始删除文件上传业务。idList={}", idList);
        if (idList.isEmpty()) {
            return Result.clientFail("主键列表不能为空");
        }
        if (batchProperty.getMaxSize() < idList.size()) {
            log.warn("删除文件上传数量超限。batch.size={} size={}", batchProperty.getMaxSize(), idList.size());
            return Result.clientFail("一次删除最多允许同时删除" + batchProperty.getMaxSize() + "条数据");
        }

        fileImportManager.fileImportManager(idList);

        log.info("删除文件上传业务结束");
        return Result.success();
    }

}
